package cn.ffcs.bpmpvc.svc;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import cn.ffcs.bpm.model.ProcTranRecord;
import cn.ffcs.bpm.model.ProcessConfigDetail;
import cn.ffcs.bpm.model.TransactProcessStatus;
import cn.ffcs.bpm.model.Transactor;
import cn.ffcs.bpmpvc.dao.AppBusinessReqDao;
import cn.ffcs.bpmpvc.dao.FlowPvcDao;
import cn.ffcs.bpmpvc.exception.FlowPvcException;
import cn.ffcs.bpmpvc.model.BpmSwimlane;
import cn.ffcs.bpmpvc.web.views.TaskView;
import cn.ffcs.organ.model.Person;

public class TaskServiceImpl implements TaskService
{
	private static final Logger logger=Logger.getLogger(TaskServiceImpl.class);
    private FlowPvcDao flowPvcDao;
    private AppBusinessReqDao appBusinessReqDao; 
    public void taskReadingToDo(String taskId,String mattersContent,String userIds[]){
    	taskReadingToDo(taskId,mattersContent,userIds,null);
    }
    
    public void taskReadingToDo(String taskId,String mattersContent,String userIds[],String taskAppExt){
        ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId));
        for (String userId : userIds)
        {
            ProcTranRecord newProcTranRecord=createTask(procTranRecord.getProcessStep(), userId, procTranRecord.getProcinstId(),TaskService.TASK_TYPE[2][0]);
            newProcTranRecord.setMatters(mattersContent);
            newProcTranRecord.setTaskAppExt(taskAppExt);
            getFlowPvcDao().save(newProcTranRecord);
        }
    }
    
    public void taskReadingToDo(ProcTranRecord procTranRecord,String mattersContent,String userIds[]){
        for (String userId : userIds)
        {
            ProcTranRecord newProcTranRecord=createTask(procTranRecord.getProcessStep(), userId, procTranRecord.getProcinstId(),TaskService.TASK_TYPE[2][0]);
            newProcTranRecord.setMatters(mattersContent);
            getFlowPvcDao().save(newProcTranRecord);
        }
    }
    
    public void taskTransferAsign(String taskId,String mattersContent,String userId){
        ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId));
        checkTaskAcitve(procTranRecord);
        procTranRecord.setTransactTime(new Date());
        Person person=getAppBusinessReqDao().getPerson(Integer.valueOf(userId));
        if(person!=null){
            procTranRecord.setMatters("将任务转派给："+person.getName());
        }
        procTranRecord.setTransactInfo(mattersContent);
        procTranRecord.setState(TASK_STATE_END);
        getFlowPvcDao().save(procTranRecord);
        
        //new新的任务
        ProcTranRecord newProcTranRecord=createTask(procTranRecord.getProcessStep(), userId, procTranRecord.getProcinstId(),TaskService.TASK_TYPE[1][0]);
        getFlowPvcDao().save(newProcTranRecord);
        //令牌转向新的任务节点
        TransactProcessStatus processStatus=getFlowPvcDao().getProcessExecuteInst(procTranRecord.getId());
        processStatus.setActId(newProcTranRecord.getId());
        getFlowPvcDao().save(processStatus);
    }
    
    public ProcTranRecord saveTaskAssignUser(String taskId,String content,List<TaskAssignBean> nextTasksList){
        ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId));
        return saveTaskAssignUser(procTranRecord,content,nextTasksList);
    }
    
    public ProcTranRecord saveTaskAssignUser(ProcTranRecord procTranRecord,String content,List<TaskAssignBean> nextTasksList){
        checkTaskAcitve(procTranRecord);
        procTranRecord.setTransactInfo(content);
        getFlowPvcDao().save(procTranRecord);
        TransactProcessStatus processStatus=getFlowPvcDao().getProcessExecuteInst(procTranRecord.getId());
        //先删除之前保存的任务人员分配信息
        getFlowPvcDao().deleteTaskAssignUser(processStatus.getId());
        Person person=null;
        ProcessConfigDetail processConfigDetail=null;
        if(nextTasksList!=null&&nextTasksList.size()>0){
        	for (TaskAssignBean taskAssignBean : nextTasksList)
            {   
                if(StringUtils.isNotBlank(taskAssignBean.getUserId())&&StringUtils.isNumeric(taskAssignBean.getUserId())){
                    person=new Person();
                    person.setId(Integer.valueOf(taskAssignBean.getUserId()));
                    Transactor transactor=new Transactor();
                    transactor.setUserId(person);
                    processConfigDetail=new ProcessConfigDetail();
                    processConfigDetail.setId(Integer.valueOf(taskAssignBean.getTaskNodeId()));
                    transactor.setProcessConfigDetail(processConfigDetail);
                    transactor.setCurrProcess(processStatus);
                    transactor.setTranType("1");
                    transactor.setBegin(new Date());
                    getFlowPvcDao().save(transactor);
                }
            }
        }
        return procTranRecord;
    }
    
    public ProcTranRecord completeTask(String taskId, List<TaskAssignBean> list)
    {
        // TODO Auto-generated method stub
        return completeTask(taskId,TaskService.TASK_COMMENT,list);
    }

    public ProcTranRecord completeTask(String taskId, String content,List<TaskAssignBean> nextTasksList)
    {
        // TODO Auto-generated method stub
        
        ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId),true);
        
        return completeTask(procTranRecord,content,nextTasksList);
    }
    
    public ProcTranRecord completeTask(ProcTranRecord procTranRecord, String content,List<TaskAssignBean> nextTasksList){
        return completeTask(procTranRecord,content,nextTasksList,null);
    }
    
    public ProcTranRecord completeTask(ProcTranRecord procTranRecord, String content,List<TaskAssignBean> nextTasksList,String toNodeId)
    {
        // TODO Auto-generated method stub
        checkTaskAcitve(procTranRecord);
        //结束任务
        procTranRecord.setTransactTime(new Date());
        procTranRecord.setTransactInfo(content);
        procTranRecord.setState(TASK_STATE_END);
        getFlowPvcDao().save(procTranRecord);
        
        //判断是否为传阅节点
        if(TaskService.TASK_TYPE[2][0].equalsIgnoreCase(procTranRecord.getTaskType())){
            return procTranRecord;
        }
        
        
        //得到流程实例信息
        TransactProcessStatus processStatus=getFlowPvcDao().getProcessExecuteInst(procTranRecord.getId());
        Integer parentId=processStatus.getParentId();
        ProcessConfigDetail currentStep=procTranRecord.getProcessStep();
        //先删除之前保存的任务人员分配信息
        getFlowPvcDao().deleteTaskAssignUser(processStatus.getId());
        if(TaskService.NODE_TYPE_END.equalsIgnoreCase(currentStep.getNodeType())){
            //结束流程
            processStatus.setEnd(new Date());
            processStatus.setState(ProcessPvcService.INACTIVE_ROOT);
            getFlowPvcDao().save(processStatus);
        }else{
            List<ProcessConfigDetail> childList=getFlowPvcDao().findNextTaskNode(currentStep.getId());
            boolean isNext=true;
            if(ProcessPvcService.ACTIVE_JOIN.equalsIgnoreCase(processStatus.getState())){
                if(childList!=null&&childList.size()==1){
                    ProcessConfigDetail nextTaskNode=(ProcessConfigDetail)childList.get(0);
                   //检查下一步是否到达join节点,3
                    if(NODE_TYPE_JOIN.equals(nextTaskNode.getNodeType())){
                        processStatus.setState(ProcessPvcService.INACTIVE_JOIN);
                        processStatus.setEnd(new Date());
                        getFlowPvcDao().save(processStatus);
                        //查看其他分支节点的信息
                        List subExecuteList=getFlowPvcDao().findProcessSubExecuteInstList(parentId, ProcessPvcService.ACTIVE_JOIN, true);
                        if(subExecuteList==null||subExecuteList.size()<=0){
                            //删除子分支令牌
                            getFlowPvcDao().deleteProcessSubExecute(parentId, ProcessPvcService.INACTIVE_JOIN);
                            processStatus=null;
                        }else{
                            isNext=false;
                        }
                    }
                }
            }
            if(processStatus==null){
                processStatus=getFlowPvcDao().getProcessExecuteInstById(parentId);
            }
            //下一步任务分配
            if(isNext){
                if(childList!=null&&childList.size()>0){
                    for (Object object : childList)
                    {
                        ProcessConfigDetail nextTaskNode=(ProcessConfigDetail)object;
                        if(NODE_TYPE_JOIN.equals(nextTaskNode.getNodeType())){
                            //继续查找一下节点
                            childList=getFlowPvcDao().findNextTaskNode(nextTaskNode.getId());
                            boolean isBreak=assignOneNextTask(nextTasksList,processStatus, childList);
                            if(isBreak){
                                break;
                            }
                        }else if(NODE_TYPE_FOK.equalsIgnoreCase(nextTaskNode.getNodeType())){
                            childList=getFlowPvcDao().findNextTaskNode(nextTaskNode.getId());
                            boolean isBreak=assignForkTask(nextTasksList,processStatus, childList);
                            if(isBreak){
                                break;
                            }
                        }else if(NODE_TYPE_END.equalsIgnoreCase(nextTaskNode.getNodeType())){
                            boolean isBreak=assignOneNextTask(nextTasksList,processStatus, childList);
                            if(isBreak){
                                break;
                            }
                        }else if(NODE_TYPE_ACITVE.equalsIgnoreCase(nextTaskNode.getNodeType())){
                            boolean isBreak=assignOneNextTask(nextTasksList,processStatus, childList);
                            if(isBreak){
                                break;
                            }
                        }
                    }
                    getFlowPvcDao().save(processStatus);
                }
            }
        }
        return procTranRecord;
    }

    private void checkTaskAcitve(ProcTranRecord procTranRecord)
    {
        if(procTranRecord==null){
            throw new FlowPvcException("Flow-ERROR01:未找到任务");
        }
        if(procTranRecord.getState().equalsIgnoreCase(TASK_STATE_END)){
            throw new FlowPvcException("Flow-ERROR02:任务已经结束，不能再提交、转派、回退");
        }
    }

    private void checkTaskNotAcitve(ProcTranRecord procTranRecord)
    {
        if(procTranRecord==null){
            throw new FlowPvcException("Flow-ERROR01:未找到任务");
        }
        if(procTranRecord.getState().equalsIgnoreCase(TASK_STATE_ACTIVE)){
            throw new FlowPvcException("Flow-ERROR04:任务执行中，不能回收");
        }
        
        if(procTranRecord.getState().equalsIgnoreCase(NODE_TYPE_END)){
            throw new FlowPvcException("Flow-ERROR05:结束任务节点，不能回收");
        }
    }
    
    private boolean assignOneNextTask(List<TaskAssignBean> nextTasksList,TransactProcessStatus processStatus, List childList)
    {
        int count=0;
        for (Object object : childList)
        {
            ProcessConfigDetail childNode=(ProcessConfigDetail)object;
            for (TaskAssignBean taskAssignBean : nextTasksList)
            {
                if(taskAssignBean.getTaskNodeId().equalsIgnoreCase(String.valueOf(childNode.getId()))){
                    //写入任务记录
                    if(StringUtils.isNotBlank(taskAssignBean.getUserId())){
                        ProcTranRecord nextProcTranRecord=createTask(childNode,taskAssignBean.getUserId(),processStatus.getProcinstId());
                        getFlowPvcDao().save(nextProcTranRecord);
                        processStatus.setActId(nextProcTranRecord.getId());
                        processStatus.setCurrProcessConfigDetail(childNode);
                        count++;
                    }
                    break;
                }
            }
        }
        if(count>0){
            return true;
        }else{
            return false;
        }
    }
    
    private ProcTranRecord createTask(ProcessConfigDetail node,String userId,Integer procInstId){
        return createTask(node,userId,procInstId,"01");
    }
    /**
     * 创建任务信息
     * TODO 请输入方法说明
     * @param node
     * @param userId
     * @param procInstId
     * @return
     */
    private ProcTranRecord createTask(ProcessConfigDetail node,String userId,Integer procInstId,String taskType){
        ProcTranRecord nextProcTranRecord=new ProcTranRecord();
        Person person=new Person();
        Date now=new Date();
        person.setId(Integer.parseInt(userId));
        nextProcTranRecord.setTransactor(person);
        nextProcTranRecord.setReceiveTime(now);
        nextProcTranRecord.setProcessConfig(node.getProcessConfig());
        nextProcTranRecord.setProcessStep(node);
        nextProcTranRecord.setProcinstId(procInstId);
        nextProcTranRecord.setState(TASK_STATE_ACTIVE);
        nextProcTranRecord.setTaskType(taskType);
        if(StringUtils.isNotBlank(node.getTimeLimit())&&StringUtils.isNumeric(node.getTimeLimit())){
            Calendar cal= Calendar.getInstance();
            cal.setTime(now);
            cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(node.getTimeLimit()));
            nextProcTranRecord.setExpireTime(cal.getTime());
        }
        if(TaskService.TASK_TYPE[1][0].equals(taskType)){
        	//保存swimlane值
            if(StringUtils.isNotBlank(node.getSwinlane())){
                BpmSwimlane bpmSwimlane=getFlowPvcDao().getBpmSwimlane(node.getSwinlane(), procInstId);
                if(bpmSwimlane==null){
                    bpmSwimlane=new BpmSwimlane();
                }
                bpmSwimlane.setAssign(userId);
                bpmSwimlane.setSwinlane(node.getSwinlane());
                bpmSwimlane.setProcinstId(procInstId);
                getFlowPvcDao().save(bpmSwimlane);
            }
            //end
        }
        
        return nextProcTranRecord;
    }
    /**
     * 创建子令牌
     * TODO 请输入方法说明
     * @param node
     * @param curProcessStatus
     * @return
     */
    private TransactProcessStatus createSubExecute(ProcessConfigDetail node,TransactProcessStatus curProcessStatus){
        TransactProcessStatus subProcessStatus=new TransactProcessStatus();
        subProcessStatus.setBegin(new Date());
        subProcessStatus.setCurrProcessConfig(node.getProcessConfig());
        subProcessStatus.setCurrProcessConfigDetail(node);
        subProcessStatus.setState(ProcessPvcService.ACTIVE_JOIN);
        subProcessStatus.setParentId(curProcessStatus.getId());
        subProcessStatus.setProcinstId(curProcessStatus.getProcinstId());
        return subProcessStatus;
    }
    
    private boolean assignForkTask(List<TaskAssignBean> nextTasksList,TransactProcessStatus processStatus, List childList)
    {
        int count=0;
        for (Object object : childList)
        {
            ProcessConfigDetail childNode=(ProcessConfigDetail)object;
            

            for (TaskAssignBean taskAssignBean : nextTasksList)
            {
                if(taskAssignBean.getTaskNodeId().equalsIgnoreCase(String.valueOf(childNode.getId()))){
                    //写入任务记录
                    if(StringUtils.isNotBlank(taskAssignBean.getUserId())){
                        //保存实例令牌信息
                        TransactProcessStatus subProcessStatus=createSubExecute(childNode,processStatus);
                        getFlowPvcDao().save(subProcessStatus);
                        //end
                        
                        ProcTranRecord nextProcTranRecord=createTask(childNode,taskAssignBean.getUserId(),processStatus.getProcinstId());
                        getFlowPvcDao().save(nextProcTranRecord);
                        subProcessStatus.setActId(nextProcTranRecord.getId());
                        count++;
                    }
                    //end
                    break;
                }
            }
        }
        processStatus.setActId(null);
        processStatus.setCurrProcessConfigDetail(null);
        if(count>0){
            return true;
        }else{
            return false;
        }
    }
    
    private void setNextNodes(TaskView taskView,Integer currentNodeId,String selCondition){
        List<ProcessConfigDetail> childList=getFlowPvcDao().findNextTaskNode(currentNodeId);
        if(childList!=null&&childList.size()>0){
        	
        	
        	ProcessConfigDetail nextTaskNode=null;
        	//根据条件查找一下流程节点
        	if(StringUtils.isNotBlank(selCondition)){
        		String nodeCondition=null;
        		for (ProcessConfigDetail childNodeOne : childList) {
        			nodeCondition=childNodeOne.getCondition();
        			if(StringUtils.isNotBlank(nodeCondition)&&selCondition.equalsIgnoreCase(nodeCondition)){
        				nextTaskNode=childNodeOne;
        				childList=new ArrayList<ProcessConfigDetail>();
                    	childList.add(nextTaskNode);
                    	break;
        			}
				}
        	}else{
        		if(childList.size()>1){
                    taskView.setIsSelect(true);
                }
        	}
        	//
        	
            if(nextTaskNode==null){
            	nextTaskNode=(ProcessConfigDetail)childList.get(0);
            }
            if(NODE_TYPE_JOIN.equals(nextTaskNode.getNodeType())){
                //继续查找一下节点
                childList=getFlowPvcDao().findNextTaskNode(nextTaskNode.getId());
            }else if(NODE_TYPE_FOK.equalsIgnoreCase(nextTaskNode.getNodeType())){
                childList=getFlowPvcDao().findNextTaskNode(nextTaskNode.getId());
            }else{
            	
            }
        }
        taskView.setChildTaskNodeList(childList);
    }
    
    public List findNextTaskNodes(Integer currentNodeId){
        List childList=getFlowPvcDao().findNextTaskNode(currentNodeId);
        if(childList!=null&&childList.size()>0){
            ProcessConfigDetail nextTaskNode=(ProcessConfigDetail)childList.get(0);
            if(NODE_TYPE_JOIN.equals(nextTaskNode.getNodeType())){
                //继续查找一下节点
                childList=getFlowPvcDao().findNextTaskNode(nextTaskNode.getId());
            }else if(NODE_TYPE_FOK.equalsIgnoreCase(nextTaskNode.getNodeType())){
                childList=getFlowPvcDao().findNextTaskNode(nextTaskNode.getId());
                
            }else if(NODE_TYPE_END.equalsIgnoreCase(nextTaskNode.getNodeType())){
                //结束流程
                //childList=null;
            }
        }
        return childList;
    }
    
    public TaskView getTaskView(String taskId){
    	return getTaskView(taskId,null,null);
    }
    
    public TaskView getTaskView(String taskId,String selCondition,Object context){
        TaskView taskView=new TaskView();
        ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId));
        procTranRecord.getProcessConfig().getName();
        procTranRecord.getTransactor().getName();
        TransactProcessStatus processStatus=getFlowPvcDao().getProcessExecuteInst(procTranRecord.getId());
        ProcessConfigDetail curStep=procTranRecord.getProcessStep();
        //转换换行符
        String tmp=curStep.getLimitExplain();
        curStep.setLimitExplain(StringUtils.replace(tmp, "\n", "<br/>"));
        tmp=curStep.getFlowExplain();
        curStep.setFlowExplain(StringUtils.replace(tmp, "\n", "<br/>"));
        //end
        
        taskView.setProcTranRecord(procTranRecord);
        setNextNodes(taskView,curStep.getId(),selCondition);
        List childTaskNodeList=taskView.getChildTaskNodeList();
        //List childTaskNodeList=findNextTaskNodes(curStep.getId());
        //taskView.setChildTaskNodeList(childTaskNodeList);
        
        //得到已经提交的人员分配信息
        if(processStatus!=null){
            List transActorList=getFlowPvcDao().findTaskAssignUser(processStatus.getId());
            if(transActorList!=null&&transActorList.size()>0){
                for (Object object : childTaskNodeList)
                {
                    ProcessConfigDetail configDetail=(ProcessConfigDetail)object;
                    for (Object object2 : transActorList)
                    {
                        Transactor transactor=(Transactor)object2;
                        if(configDetail.getId().intValue()==transactor.getProcessConfigDetail().getId().intValue()){
                            configDetail.setPerson(transactor.getUserId());
                            break;
                        }
                    }
                }
            }else{
                //从swimlane中取得节点用户信息
                List<BpmSwimlane> swinlaneList=getFlowPvcDao().findBpmSwimlaneList(processStatus.getProcinstId());
                if(swinlaneList!=null&&swinlaneList.size()>0){
                    Person person=null;
                    for (Object object : childTaskNodeList)
                    {
                        ProcessConfigDetail configDetail=(ProcessConfigDetail)object;
                        
                        if(StringUtils.isNotBlank(configDetail.getSwinlane())){
                            for (BpmSwimlane bpmSwimlane : swinlaneList)
                            {
                                if(bpmSwimlane.getSwinlane().equalsIgnoreCase(configDetail.getSwinlane())){
                                	
                                    person=new Person();
                                    person.setId(Integer.valueOf(bpmSwimlane.getAssign()));
                                    person.setName(bpmSwimlane.getAssingName());
                                    configDetail.setPerson(person);
                                    break;
                                }
                            }
                        }
                    }
                }
                //取权限角色下拉用户
                for (Object object : childTaskNodeList)
                {
                    ProcessConfigDetail configDetail=(ProcessConfigDetail)object;
                    if(StringUtils.isNotBlank(configDetail.getSecRole())){
                        List<Person> perSonList=getFlowPvcDao().findPersonByRoleName(configDetail.getSecRole(),true);
                        configDetail.setPersonList(perSonList);
                    }else if(StringUtils.isNotBlank(configDetail.getAssignHandlerClass())){
                    	try {
							TaskAssignHandler assignHandler=(TaskAssignHandler)Class.forName(configDetail.getAssignHandlerClass()).newInstance();
							List<Person> perSonList=assignHandler.executeAssign(processStatus,context);
							configDetail.setPersonList(perSonList);
						} catch (InstantiationException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IllegalAccessException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (ClassNotFoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
                    }
                }
                //end
            }
            //取得节点对应要提交的文档类型
            List documentTypes=getFlowPvcDao().findDocumentTypeByNodeId(curStep.getId());
            taskView.setDocumentTypes(documentTypes);
        }
        //取得办理步骤信息
        List flowTaskList=getFlowPvcDao().findTaskList(procTranRecord.getProcinstId());
        taskView.setFlowTaskList(flowTaskList);
        return taskView;
    }
    
    public void recyclingTask(String taskId,String userId,String content){
        ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId));
        procTranRecord.setOrderBy(2);
        getFlowPvcDao().save(procTranRecord);
        checkTaskNotAcitve(procTranRecord);
        ProcessConfigDetail currentStep=procTranRecord.getProcessStep();
        //查看后续任务是否处于执行状态
        Integer procInstId=procTranRecord.getProcinstId();
        List childList=getFlowPvcDao().findNextTaskNode(currentStep.getId());
        if(childList!=null&&childList.size()>0){
        	Integer nodeIdArr[]=null;
        	for (Object node : childList) {
        		
        		ProcessConfigDetail nextTaskNode=(ProcessConfigDetail)node;
                //检查下一步是否join 或fok节点
                if(NODE_TYPE_JOIN.equals(nextTaskNode.getNodeType())||NODE_TYPE_FOK.equals(nextTaskNode.getNodeType())){
                    //继续查找
                   List childNextList=getFlowPvcDao().findNextTaskNode(nextTaskNode.getId());
                   //检查节点是否处于活动状态
                   int i=0;
                   nodeIdArr=new Integer[childNextList.size()];
                   for (Object object : childNextList)
                   {
                       ProcessConfigDetail tmp=(ProcessConfigDetail)object;
                       nodeIdArr[i]=tmp.getId();
                       i++;    
                   }
                }else{
                	nodeIdArr=new Integer[1];
                	nodeIdArr[0]=nextTaskNode.getId();
                }
                //检查节点是否处于活动状态
                List allexecuteList=getFlowPvcDao().findAllExecuteList(procInstId, nodeIdArr);
                if(allexecuteList==null||allexecuteList.size()==0){
                	continue;
                }
                List executeList=getFlowPvcDao().findRunExecuteList(procInstId, nodeIdArr);
                if(executeList==null||executeList.size()<=0||allexecuteList==null||allexecuteList.size()<=0||(executeList.size()!=allexecuteList.size())){
                    throw new FlowPvcException("Flow-ERROR06:下一步任务已结束，不能回收");
                }
                
                //结束子任务
                TransactProcessStatus nextCurrentStatus=null;
                for (Object object2 : executeList)
                {
                    nextCurrentStatus=(TransactProcessStatus)object2;
                    getFlowPvcDao().updateCompleteTask(nextCurrentStatus.getActId(), content);
                }
                //创建新任务
                ProcTranRecord newTask=createTask(currentStep, userId, procInstId);
                getFlowPvcDao().save(newTask);
                //当为join节点时
                if(NODE_TYPE_JOIN.equals(nextTaskNode.getNodeType())){
                    
                    //设置父令牌
                    nextCurrentStatus.setActId(null);
                    nextCurrentStatus.setState(ProcessPvcService.ACTIVE_CONCURRENT_ROOT);
                    nextCurrentStatus.setCurrProcessConfigDetail(null);
                    getFlowPvcDao().save(nextCurrentStatus);
                    
                    //保存子令牌
                    TransactProcessStatus subProcessStatus=createSubExecute(currentStep, nextCurrentStatus);
                    subProcessStatus.setActId(newTask.getId());
                    getFlowPvcDao().save(subProcessStatus);
                    
                }else if(NODE_TYPE_FOK.equals(nextTaskNode.getNodeType())){
                    //当为fok节点
                    //删除对应的子令牌
                    getFlowPvcDao().deleteProcessSubExecute(nextCurrentStatus.getParentId());
                    //得到父令牌
                    TransactProcessStatus parentExecuteStatus=getFlowPvcDao().getProcessExecuteInstById(nextCurrentStatus.getParentId());
                    parentExecuteStatus.setActId(newTask.getId());
                    parentExecuteStatus.setCurrProcessConfigDetail(currentStep);
                    getFlowPvcDao().save(parentExecuteStatus);
                }else{
                    nextCurrentStatus.setActId(newTask.getId());
                    nextCurrentStatus.setCurrProcessConfigDetail(currentStep);
                    getFlowPvcDao().save(nextCurrentStatus);
                }
			}
        }
    }
    
    public void assignTaskUser(String taskId, String userId)
    {
        // TODO Auto-generated method stub
        ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId));
        checkTaskAcitve(procTranRecord);
        TransactProcessStatus processStatus=getFlowPvcDao().getProcessExecuteInst(Integer.parseInt(taskId));
        //结束原来的任务
        procTranRecord.setOrderBy(2);
        procTranRecord.setTransactTime(new Date());
        procTranRecord.setState(TASK_STATE_END);
        procTranRecord.setTransactInfo("任务转派："+userId);
        getFlowPvcDao().save(procTranRecord);
        //启动一个新的转派任务
        ProcTranRecord procTranRecordTmp=createTask(procTranRecord.getProcessStep(),userId,processStatus.getProcinstId());
        getFlowPvcDao().save(procTranRecordTmp);
        //回写任务ID到令牌中
        processStatus.setActId(procTranRecordTmp.getId());
        getFlowPvcDao().save(processStatus);
    }
    
    public void assignTaskToUser(String taskId, String userId){
    	ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId));
        checkTaskAcitve(procTranRecord);
        Person person=new Person();
        person.setId(Integer.valueOf(userId));
        procTranRecord.setTransactor(person);
        getFlowPvcDao().save(procTranRecord);
    }
    
    public void rollBackTask(String taskId,String content){
    	 ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId),true);
    	 rollBackTask(procTranRecord,content);
    }
    
    public void rollBackTask(ProcTranRecord procTranRecord,String content)
    {
        // TODO Auto-generated method stub
    	logger.info("任务回退start:"+procTranRecord.getId());
        checkTaskAcitve(procTranRecord);
        //对于开始节点不能回退
        ProcessConfigDetail currentStep=procTranRecord.getProcessStep();
        checkIsStartNode(currentStep);
        //结束当前状态
        procTranRecord.setTransactTime(new Date());
        procTranRecord.setTransactInfo(content);
        procTranRecord.setState(TASK_STATE_END);
        procTranRecord.setOrderBy(2);
        procTranRecord.setMatters("任务回退");
        getFlowPvcDao().save(procTranRecord);
        
        
        
        //得到流程实例信息
        TransactProcessStatus processStatus=getFlowPvcDao().getProcessExecuteInst(procTranRecord.getId());
        //查找前一步骤节点
        List parentList=getFlowPvcDao().findPretTaskNode(currentStep.getId());
        if(parentList!=null&&parentList.size()>0){
        	List list=new ArrayList();
        	//判断回退节点是否都为普通的节点，如果是取最近的节点进行回退
        	int count=0;
        	Integer nodeIdArr[]=new Integer[parentList.size()];;
        	for (Object node : parentList) {
        		ProcessConfigDetail preStep=(ProcessConfigDetail)node;
        		if(TaskService.NODE_TYPE_ACITVE.equals(preStep.getNodeType())||TaskService.NODE_TYPE_START.equals(preStep.getNodeType())){
        			nodeIdArr[count]=preStep.getId();
        			count++;
        		}
        	}
        	if(parentList.size()==count){
        		
        		//选择最近的节点
        		List<ProcTranRecord> preTaskList=getFlowPvcDao().findTaskList(processStatus.getProcinstId(), nodeIdArr);
        		if(preTaskList!=null&&preTaskList.size()>0){
        			saveRollBackTask(processStatus,preTaskList.get(0));
        		}else{
        			throw new FlowPvcException("Flow-ERROR07:对不起未找到回退任务节点！");
        		}
        	}else{
            	for (Object node : parentList) {
            		ProcessConfigDetail preStep=(ProcessConfigDetail)node;
                    //对于join节点需要往前找
            		Integer idArr[];
                    if(TaskService.NODE_TYPE_JOIN.equals(preStep.getNodeType())||TaskService.NODE_TYPE_FOK.equals(preStep.getNodeType())){
                        List parentNextList=getFlowPvcDao().findPretTaskNode(preStep.getId());
                        idArr=new Integer[parentNextList.size()];
                        int i=0;
                        for (Object object : parentNextList)
                        {
                            ProcessConfigDetail tmp=(ProcessConfigDetail)object;
                            idArr[i]=tmp.getId();
                            i++;
                        }
                    }else{
                    	idArr=new Integer[1];
                    	idArr[0]=preStep.getId();
                    }
                    
                    List<ProcTranRecord> preTaskList=getFlowPvcDao().findTaskList(processStatus.getProcinstId(), idArr);
                    if(preTaskList!=null&&preTaskList.size()>0){
                    	//查找回退节点用户信息
                        if(TaskService.NODE_TYPE_JOIN.equals(preStep.getNodeType())){
                            //创建分支令牌信息
                           for (ProcTranRecord procTranRecord2 : preTaskList)
                           {
                               procTranRecord2.setOrderBy(2);
                               getFlowPvcDao().save(procTranRecord2);
                               //保存实例令牌信息
                               TransactProcessStatus subProcessStatus=createSubExecute(procTranRecord2.getProcessStep(),processStatus);
                               getFlowPvcDao().save(subProcessStatus);
                               
                               ProcTranRecord nextProcTranRecord=createTask(procTranRecord2.getProcessStep(),String.valueOf(procTranRecord2.getTransactor().getId()),processStatus.getProcinstId());
                               
                               getFlowPvcDao().save(nextProcTranRecord);
                               subProcessStatus.setActId(nextProcTranRecord.getId());
                               processStatus.setCurrProcessConfigDetail(null);
                               processStatus.setActId(null);
                               getFlowPvcDao().save(processStatus);
                           }
                        }else if(TaskService.NODE_TYPE_FOK.equals(preStep.getNodeType())){
                            //结束分支上的信息
                            Integer parentExecuteId=processStatus.getParentId();
                            String rollBackInfo="由"+procTranRecord.getTransactor().getName()+"回退结束！";
                            getFlowPvcDao().updateCompletForkTask(parentExecuteId,rollBackInfo);
                            getFlowPvcDao().deleteProcessSubExecute(parentExecuteId);
                            processStatus=getFlowPvcDao().getProcessExecuteInstById(parentExecuteId);
                            saveRollBackTask(processStatus, preTaskList);
                        }else{
                            saveRollBackTask(processStatus, preTaskList);
                        }
                    }
    			}
        	}
        }
        logger.info("任务回退end");
    }
    
    public void saveSwimlance(String assignUserId,String swinlaneName,Integer procinstId){
    	BpmSwimlane bpmSwimlane=getFlowPvcDao().getBpmSwimlane(swinlaneName, procinstId);
        if(bpmSwimlane==null){
        	bpmSwimlane=new BpmSwimlane();
        }
        bpmSwimlane.setAssign(assignUserId);
        bpmSwimlane.setProcinstId(procinstId);
        bpmSwimlane.setSwinlane(swinlaneName);
        getFlowPvcDao().save(bpmSwimlane);
    }
    
    public ProcTranRecord completeTaskAndProcess(String taskId, String content)
    {
        // TODO Auto-generated method stub
    	ProcTranRecord procTranRecord=getFlowPvcDao().getTask(Integer.parseInt(taskId),true);
        checkTaskAcitve(procTranRecord);
        //结束任务
        procTranRecord.setTransactTime(new Date());
        procTranRecord.setTransactInfo(content);
        procTranRecord.setState(TASK_STATE_END);
        getFlowPvcDao().save(procTranRecord);
        
        //判断是否为传阅节点
        if(TaskService.TASK_TYPE[2][0].equalsIgnoreCase(procTranRecord.getTaskType())){
            return procTranRecord;
        }
        
        //得到流程实例信息
        TransactProcessStatus processStatus=getFlowPvcDao().getProcessExecuteInst(procTranRecord.getId());
        ProcessConfigDetail currentStep=procTranRecord.getProcessStep();
        //先删除之前保存的任务人员分配信息
        getFlowPvcDao().deleteTaskAssignUser(processStatus.getId());
        if(TaskService.NODE_TYPE_START.equalsIgnoreCase(currentStep.getNodeType())){
        	//结束流程
            //processStatus.setEnd(new Date());
            //processStatus.setState(ProcessPvcService.INACTIVE_ROOT);
            //getFlowPvcDao().save(processStatus);
           getFlowPvcDao().endProcessInst(String.valueOf(procTranRecord.getProcinstId()));
        }
        return procTranRecord;
    }
    
    private void saveRollBackTask(TransactProcessStatus processStatus,ProcTranRecord preProcTranRecord)
    {
    	preProcTranRecord.setOrderBy(2);
        getFlowPvcDao().save(preProcTranRecord);
        ProcTranRecord nextProcTranRecord=createTask(preProcTranRecord.getProcessStep(),String.valueOf(preProcTranRecord.getTransactor().getId()),processStatus.getProcinstId());          
        getFlowPvcDao().save(nextProcTranRecord);
        processStatus.setActId(nextProcTranRecord.getId());
        processStatus.setCurrProcessConfigDetail(preProcTranRecord.getProcessStep());
        getFlowPvcDao().save(processStatus);
    }

    private void saveRollBackTask(TransactProcessStatus processStatus,List<ProcTranRecord> preTaskList)
    {
        for (ProcTranRecord procTranRecord2 : preTaskList)
        {
            procTranRecord2.setOrderBy(2);
            getFlowPvcDao().save(procTranRecord2);
            ProcTranRecord nextProcTranRecord=createTask(procTranRecord2.getProcessStep(),String.valueOf(procTranRecord2.getTransactor().getId()),processStatus.getProcinstId());          
            getFlowPvcDao().save(nextProcTranRecord);
            processStatus.setActId(nextProcTranRecord.getId());
            processStatus.setCurrProcessConfigDetail(procTranRecord2.getProcessStep());
            getFlowPvcDao().save(processStatus);
        }
    }
    private void checkIsStartNode(ProcessConfigDetail currentStep)
    {
        if(TaskService.NODE_TYPE_START.equalsIgnoreCase(currentStep.getNodeType())){
            throw new FlowPvcException("Flow-ERROR03:开始节点不能回退");
        }
    }

    public FlowPvcDao getFlowPvcDao()
    {
        return flowPvcDao;
    }

    public void setFlowPvcDao(FlowPvcDao flowPvcDao)
    {
        this.flowPvcDao = flowPvcDao;
    }

    public AppBusinessReqDao getAppBusinessReqDao()
    {
        return appBusinessReqDao;
    }

    public void setAppBusinessReqDao(AppBusinessReqDao appBusinessReqDao)
    {
        this.appBusinessReqDao = appBusinessReqDao;
    }


    
}
